package com.myBlog.services.Article;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.myBlog.controller.DictController;
import com.myBlog.pojo.UserArticle;
import com.myBlog.pojo.dict.Type;
import com.myBlog.repository.UserArticleMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
@Slf4j
@EnableScheduling
public class ArticleCaches {
    @Autowired
    private UserArticleService userArticleService;

    @Autowired
    private UserArticleMapper userArticleMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private DictController dictController;

    private static final String dictCacheKey = "dict_map";
    private static final String allCacheKey = "all";

    private static int AllLimit = 4;

    private String getCacheKey(String type){
        if(type==null){
            return allCacheKey;
        }

        return type;
    }

    public Page<UserArticle> getCache(int pageNum, int pageSize, String type){
        Page<UserArticle> articlePage = new Page<>();
        String cachedKey = this.getCacheKey(type);
        if(cachedKey!=null){
            long size = redisTemplate.opsForList().size(cachedKey);
            if(cachedKey.equals(allCacheKey)){
                articlePage.setCurrent(pageNum);
                articlePage.setSize(size);
                articlePage.setTotal(size);
                articlePage.setRecords( redisTemplate.opsForList().range( cachedKey,0,-1 ) );
            }else {
                articlePage.setCurrent(pageNum);
                articlePage.setSize(pageSize);
                articlePage.setTotal(size);
                articlePage.setRecords( redisTemplate.opsForList().range(cachedKey, (pageNum - 1) * pageSize, size <= (pageNum * pageSize - 1) ? size : (pageNum * pageSize - 1)) );
            }
        }
        return articlePage;
    }

    private void setCache(List<UserArticle> articleList, String cache){
        redisTemplate.delete(cache);
        if(!articleList.isEmpty()){
            redisTemplate.opsForList().rightPushAll(cache,articleList);
        }
    }

    @Scheduled(fixedDelay = 1200000)
    public void scheduleCache(){
        dictController.getDictObject();
        JSONObject dict_map = (JSONObject) redisTemplate.opsForValue().get(dictCacheKey);
        if(dict_map==null){
            return;
        }
        List<Type> types = dict_map.getList("types", Type.class);

        this.refreshCache(allCacheKey);
        for(Type type:types){
            this.refreshCache(type.getTypeKey());
        }
    }

    // 更新redis的缓存
    private void refreshCache(String cacheKey){
        log.info("文章列表缓存定时任务开始：{}", cacheKey);
        List<UserArticle> dataList = null;
        if( cacheKey.equals( allCacheKey ) ){
            dataList = userArticleMapper.getHomeData(AllLimit);
        }else {
            dataList = userArticleService.list( new QueryWrapper<UserArticle>().eq("type",cacheKey ).eq("status","1").orderByDesc("replease_time") );
        }

        this.setCache( dataList, cacheKey );
        log.info("文章列表缓存定时任务结束：{}", cacheKey);
    }
}
